The Action interface in Swing has a setEnabled() and an isEnabled() property that
lets you enable/disable actions (and any menus they were added to) by a simple call
to the setEnabled(false).
It would be nice if one could call setEnabled()/isEnabled() on a EditAction after
getting it from the jEdit.getAction(String Name) and have it automatically work as
it should in Swing.
This would be a first step in unifying the jEdit and Swing action API. But doing this
would also require reworking the GuiUtilities.loadMenuItem() methods so they create
JMenuItems with a Swing Action inside them instead of the multiple separate arguments
that are currently supplied to the JMenuItem ctor.
The current way of enabling/disabling menu items (we can see an example in the toggle
buffer switcher code) is not reusable.
Submitted | ezust - 2009-08-10 - 21:25:32z | Assigned | nobody |
---|---|---|---|
Priority | 5 | Category | core |
Status | Open | Group | None |
Resolution | None | Visibility | No |
2009-12-30 - 20:33:24z ezust |
Looks like I need to do this myself in order to unify HelperLauncher/ProjectViewer. I will also need to support full sets of properties, including dynamic labels which can be chosen at the time the menu is created. |
---|---|
2010-02-22 - 20:17:28z ezust |
Post by Francois Rey on jEdit-devel which I think is relevant, so I am going to paste
it here: --- cut here --- Over a month ago while writing the Launcher plugin I started a thread because I needed help in clarifying how to best use Action, ActionSet, etc. I got some answers but nothing gave me a clear sense of direction, I was more confused. Back then I wrote a reply while carrying out my own investigation. It didn't look so contructive, so I just kept the mail in my draft folder. However recent discussions on how to improve Launcher before release showed me how 'hot' this topic is. The need for some refactoring in this area is shared, as well as the understanding this would be an involved work. I'm unable carry that work (other priorities require my attention) however the draft email I wrote, while not really constructive, could serve as my 2cts and give a nice overview of what's confusing with present situation. To summarize, here's what's the most confusing for me: 1. Actions are both stateful and stateless without clear indication when they are and when they're not 2. When stateful, state is not necessarily used in action invoke() logic 3. ActionContext has more to do with managing Action than giving context 4. Top level classes make strong assumptions that Action are implemented with beanshell code Here's the longer version (draft email with minor edits): On Saturday 16 January 2010 01:57:05 Alan Ezust wrote: > Yes, PV has its own hierarchy of actions, which is kinda annoying. But > that's because jedit's built-in actions were not sufficient for the job at > the time, I suppose. Probably, yes, and I realize this Action/ActionSet/ActionContext has a long history. These classes have grown organically and that's part of my confusion: I don't seem to be able to see a clear intent in them, or if there is/was, it seems diluted at various places and the names only help a little. For example, at first glance the framework seems to indicate that Actions should not have state so the same instance can be reused and applied several times. So you think the context is what changes across invocations. But when you look at the the Action api, it never references any ActionContext, because ActionContext are just manager of ActionSet (it even says so in the javadoc). It's only through the indirection of its own invoke() method that an ActionContext can prepare some contextual information before calling action.invoke(), as it is the case for BrowserActionContext defined in VFSBrowser.java. In other words the mechanism by which an action logic knows its contextual information is outside the scope of the action framework api. In fact, as far as Actions are concerned, ActionContext does not exist. If you look at FSB code here's what's happening: context information is given by the *global* beanshell namespace to beanshell actions. The same ActionContext instance is used for managing sets of stateless Actions, so it has nothing specific to the action about to be invoked since it's the same context for all actions. So in terms of name it has nothing to do with context, and more to do with an <ActionSet>Manager that only deals with context if one cares to use it as intermediates for invoking actions. While FSB actions are somewhate stateless, PV Actions are clearly stateful and make no use of ActionContext. The PV method Action.prepareForNode() is a clear illustration of that. So the two existing components that already do something similar to what the Launcher plugin does are far appart from each other in the way they use Action and ActionContext. Moreover, when looking at top level framework class JEditAbstractEditAction you realize actions aren't meant to be stateless after all. There is a protected instance variable of type Object[] which is first initialized in the contructor, and then modified by the invoke method that has an additional Object[] parameter. However the latter does not seem to be aimed at containing the actual logic of the action: it just memorize the array and call the other invoke method which is abstract. So what are these arguments for? The subclass EditAction.getLabel() uses them to compute the label, which as nothing to do with action parameters. LoadPerspectiveAction, private class of DockingLayoutManager, uses it in its invoke() logic, so in that case they're really contextual information for the invoke logic. Another thing that makes me wonder how to best use current framework classes: the abstract method JEditActionSet.createBeanShellAction() implies that the semantic of ActionSet is dependent of BeanShell. In fact, ActionSet, GUIUtilities, EnhancedMenu, all have strong assumptions that EditActions logic are implemented with BeanShell scripting. So the framework is sending strong signals that Action must be implemented with BeanShell so you should think twice if you don't. However not all actions are (best) implemented in beanshell and I guess that's part of the reason why not all actions can be recorded as macros. I do however understand why we would prefer beanshell actions: they're obviously stateless, and they can be easily recorded! One way to make things clearer in that respect would be to have a getReplayCode() in a ReplayableAction interface (or RecordableAction?). This would not imply that all actions have to have beanshell code, and would offer a chance for any action to provide a replay beanshell code even if they're not beanshell actions. So overall I feel like the framework make strong statement here and there that are not always holding true everywhere. Hence all the head scratching when determining what's the best API for a new plugin like Launcher. |